<template>
  <div class="notification-container">
    <div class="notification-header">
      <h2>消息通知</h2>
      <div class="header-actions">
        <button @click="refreshNotifications">刷新</button>
        <button @click="markAllAsRead">全部已读</button>
        <button @click="deleteAll">全部删除</button>
        <div class="filter">
          <select v-model="selectedFilter" @change="handleFilterChange">
            <option value="all">全部</option>
            <option value="1">一般信息</option>
            <option value="2">进度提醒</option>
            <option value="3">预警</option>
            <option value="4">未读消息</option>
            <option value="5">已读消息</option>
          </select>
        </div>
      </div>
    </div>

    <div class="notification-list" @scroll="handleScroll" ref="notificationList">
      <div v-for="item in notifications" :key="item.userNotificationId"
        :class="['notification-item', { unread: !item.isRead }]" @click="handleItemClick(item)">
        <div class="notification-icon">
          <svg-icon :icon-class="getIconClass(item.notificationType)" />
        </div>
        <div class="notification-content">
          <p class="title">{{ item.title }}</p>
          <p class="message">{{ item.message }}</p>
          <p class="time">{{ formatTime(item.createdAt) }}</p>
        </div>
        <span v-if="!item.isRead" class="unread-dot" />
        <span class="close-btn" @click.stop="deleteSingle(item.userNotificationId)">
          ×
        </span>
      </div>

      <div v-if="loading" class="loading">
        <div class="loading-spinner"></div>
        <p>正在加载更多消息...</p>
      </div>

      <div v-if="finished && notifications.length > 0 && !loading" class="no-more">
        <p>没有更多消息了</p>
      </div>
    </div>

    <div v-if="!loading && !notifications.length" class="empty-notification">
      <p>暂无消息通知</p>
    </div>
  </div>
</template>

<script>
import { getUser } from "@/utils/storage";
import {
  fetchNotifications,
  markNotificationRead,
  markAllNotificationsRead,
  deleteNotification,
  deleteAllNotifications,
  getNotificationsAfterId,
} from "@/api/notification";

export default {
  name: "Notification",
  data() {
    return {
      userId: null,
      notifications: [],
      selectedFilter: "all",
      // 分页
      pageSize: 10,
      lastUserNotificationId: undefined,
      loading: false,
      finished: false,
      // 轮询
      pollingTimer: null,
      pollingInterval: 5 * 60 * 1000, // 5分钟
      lastPollingTime: null,
    };
  },
  created() {
    const user = getUser();
    this.userId = user.userId;
  },
  mounted() {
    this.loadNotifications();
    this.startPolling();
  },
  beforeDestroy() {
    this.stopPolling();
  },
  methods: {
    // 加载通知列表
    async loadNotifications() {
      if (this.loading) {
        return;
      }
      // 如果是第一页加载且finished为true，重置状态
      if (!this.lastUserNotificationId && this.finished) {
        this.finished = false;
      }

      if (this.finished) {
        return;
      }

      this.loading = true;

      const startTime = Date.now();

      try {
        const params = {
          userId: this.userId,
          pageSize: this.pageSize,
        };

        // 如果不是第一页，添加lastUserNotificationId
        if (this.lastUserNotificationId) {
          params.lastUserNotificationId = this.lastUserNotificationId;
        }

        // 如果选择了特定类型，添加notificationType
        if (this.selectedFilter !== "all") {
          params.notificationType = parseInt(this.selectedFilter);
        }

        // 检查用户ID是否存在
        if (!this.userId) {
          this.$message && this.$message.error("用户信息错误");
          return;
        }

        const response = await fetchNotifications(params);

        if (response.success && response.result) {
          const list = response.result;

          // 如果是第一页，直接替换数据
          if (!this.lastUserNotificationId) {
            this.notifications = list;
          } else {
            this.notifications = this.notifications.concat(list)
          }

          // 判断是否还有更多数据
          if (list.length < this.pageSize) {
            this.finished = true;
          }
          // 更新lastUserNotificationId
          if (list.length > 0) {
            this.lastUserNotificationId =
              list[list.length - 1].userNotificationId;
          }
        } else {
          console.error("API返回失败:", response);
          this.$message && this.$message.error("获取消息失败");
        }
      } catch (error) {
        console.error("加载通知失败:", error);
        this.$message && this.$message.error("加载通知失败");
      } finally {
        // 确保最少显示2s的加载动画
        const elapsedTime = Date.now() - startTime;
        const minLoadingTime = 2000;

        if (elapsedTime < minLoadingTime) {
          setTimeout(() => {
            this.loading = false;
          }, minLoadingTime - elapsedTime);
        } else {
          this.loading = false;
        }
      }
    },

    // 滚动加载更多
    handleScroll(e) {
      const { scrollTop, clientHeight, scrollHeight } = e.target;
      // 当滚动到距离底部20px时触发加载
      if (scrollTop + clientHeight >= scrollHeight - 20) {
        this.loadNotifications();
      }
    },

    // 过滤条件改变
    handleFilterChange() {
      this.notifications = [];
      this.lastUserNotificationId = undefined;
      this.finished = false;
      this.loading = false; // 确保重置加载状态
      this.loadNotifications();
      // 重新开始轮询
      this.startPolling();
    },

    getIconClass(type) {
      const icons = {
        1: "example", // 一般信息
        2: "schedule", // 进度提醒
        3: "verify", // 预警
      };
      return icons[type] || "example";
    },

    formatTime(time) {
      if (!time) return "";
      return new Date(time).toLocaleString("zh-CN");
    },

    // 标记单条为已读
    async markAsRead(userNotificationId) {
      try {
        const response = await markNotificationRead({
          userId: this.userId,
          userNotificationId: userNotificationId,
        });

        if (response.success) {
          // 本地更新状态
          const notification = this.notifications.find(
            (item) => item.userNotificationId === userNotificationId
          );
          if (notification && !notification.isRead) {
            notification.isRead = 1;
            notification.readAt = new Date().toISOString();
          }
        }
      } catch (error) {
        console.error("标记已读失败:", error);
        this.$message && this.$message.error("标记已读失败");
      }
    },

    // 标记全部为已读
    async markAllAsRead() {
      if (this.notifications.length === 0) {
        this.$message && this.$message.info("没有消息可标记");
        return;
      }

      try {
        const response = await markAllNotificationsRead({
          userId: this.userId,
        });

        if (response.success) {
          // 本地更新所有未读消息状态
          this.notifications.forEach((item) => {
            if (!item.isRead) {
              item.isRead = 1;
              item.readAt = new Date().toISOString();
            }
          });

          this.$message && this.$message.success("全部标记为已读");
        }
      } catch (error) {
        console.error("标记全部已读失败:", error);
        this.$message && this.$message.error("标记全部已读失败");
      }
    },

    // 删除全部
    async deleteAll() {
      if (this.notifications.length === 0) {
        this.$message && this.$message.info("没有消息可删除");
        return;
      }

      if (confirm("确定要删除所有消息吗？此操作不可恢复。")) {
        try {
          const response = await deleteAllNotifications({
            userId: this.userId,
          });

          if (response.success) {
            this.notifications = [];
            this.lastUserNotificationId = undefined;
            this.finished = false;
            this.loading = false; // 重置加载状态
            this.$message && this.$message.success("所有消息已删除");
          }
        } catch (error) {
          console.error("删除全部失败:", error);
          this.$message && this.$message.error("删除全部失败");
        }
      }
    },

    // 删除单条
    async deleteSingle(userNotificationId) {
      if (confirm("确定要删除这条消息吗？")) {
        try {
          const response = await deleteNotification({
            userId: this.userId,
            userNotificationId: userNotificationId,
          });

          if (response.success) {
            const index = this.notifications.findIndex(
              (item) => item.userNotificationId === userNotificationId
            );
            if (index !== -1) {
              this.notifications.splice(index, 1);
            }
            this.$message && this.$message.success("删除成功");
          }
        } catch (error) {
          console.error("删除失败:", error);
          this.$message && this.$message.error("删除失败");
        }
      }
    },

    // 处理消息项点击
    async handleItemClick(item) {
      // 如果未读，先标记为已读
      if (!item.isRead) {
        await this.markAsRead(item.userNotificationId);
        // 立即更新本地状态，提供即时反馈
        item.isRead = 1;
        item.readAt = new Date().toISOString();
      }
      // 跳转到详情页面
      this.viewDetail(item.userNotificationId);
    },

    // 查看消息详情
    viewDetail(userNotificationId) {
      this.$router.push(`/notify/detail/${userNotificationId}`);
    },

    // 开始轮询
    startPolling() {
      this.stopPolling(); // 先停止之前的轮询
      this.pollingTimer = setInterval(() => {
        this.pollNewNotifications();
      }, this.pollingInterval);
    },

    // 停止轮询
    stopPolling() {
      if (this.pollingTimer) {
        clearInterval(this.pollingTimer);
        this.pollingTimer = null;
      }
    },

    // 轮询新消息
    async pollNewNotifications() {
      try {
        // 如果有消息，使用第一条消息的ID作为起始点
        if (this.notifications.length > 0) {
          const firstUserNotificationId =
            this.notifications[0].userNotificationId;
          const response = await getNotificationsAfterId({
            userId: this.userId,
            userNotificationId: firstUserNotificationId,
          });

          if (
            response.success &&
            response.result &&
            response.result.length > 0
          ) {
            // 将新消息添加到最前面
            this.notifications.unshift(...response.result);

            // 显示新消息提示
            this.$message &&
              this.$message.success(`收到 ${response.result.length} 条新消息`);
          }
        } else {
          // 如果没有消息，重新加载所有消息
          this.loadNotifications();
        }
      } catch (error) {
        console.error("轮询新消息失败:", error);
      }
    },

    // 手动刷新消息
    async refreshNotifications() {
      try {
        // 强制重置loading状态
        this.loading = false;

        // 重新加载所有消息
        this.notifications = [];
        this.lastUserNotificationId = undefined;
        this.finished = false;

        // 重新加载消息
        await this.loadNotifications();
        this.$message && this.$message.success("消息已刷新");
      } catch (error) {
        console.error("刷新消息失败:", error);
        this.$message && this.$message.error("刷新失败");
      } finally {
        this.loading = false;
      }
    },
  },
};
</script>

<style scoped>
.notification-container {
  width: 100%;
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.notification-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  border-bottom: 1px solid #eee;
  padding-bottom: 15px;
}

.notification-header h2 {
  margin: 0;
  font-size: 24px;
  color: #333;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 15px;
}

.header-actions button {
  background-color: #f0f0f0;
  border: none;
  padding: 8px 15px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  color: #555;
  transition: background-color 0.3s;
}

.header-actions button:hover {
  background-color: #e0e0e0;
}

.filter select {
  padding: 8px 15px;
  border: 1px solid #ddd;
  border-radius: 4px;
  background-color: #fff;
  font-size: 14px;
  color: #555;
}

.notification-list {
  display: flex;
  flex-direction: column;
  gap: 15px;
  max-height: 700px;
  overflow-y: auto;
  padding-right: 10px;
  /* 自定义滚动条 */
  scrollbar-width: thin;
  scrollbar-color: #ccc transparent;
}

.notification-list::-webkit-scrollbar {
  width: 6px;
}

.notification-list::-webkit-scrollbar-track {
  background: transparent;
}

.notification-list::-webkit-scrollbar-thumb {
  background-color: #ccc;
  border-radius: 3px;
}

.notification-list::-webkit-scrollbar-thumb:hover {
  background-color: #999;
}

.notification-item {
  display: flex;
  align-items: center;
  padding: 15px;
  border-radius: 6px;
  transition: background-color 0.3s;
  border: 1px solid #eee;
  cursor: pointer;
  position: relative;
}

.notification-item.unread {
  background-color: #f0f8ff;
  border-left: 3px solid #1e88e5;
}

.notification-item:hover {
  background-color: #f8f8f8 !important;
}

.notification-item.unread:hover {
  background-color: #e3f2fd !important;
  border-left: 3px solid #1976d2;
}

.notification-icon {
  width: 40px;
  height: 40px;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-right: 15px;
  flex-shrink: 0;
}

.notification-icon .svg-icon {
  width: 20px;
  height: 20px;
  color: #555;
}

.notification-content {
  flex-grow: 1;
}

.notification-content .title {
  margin: 0 0 5px 0;
  font-size: 16px;
  font-weight: 600;
  color: #333;
}

.notification-content .message {
  margin: 0 0 8px 0;
  font-size: 14px;
  color: #666;
  line-height: 1.4;
}

.notification-content .time {
  margin: 0;
  font-size: 12px;
  color: #999;
}

.unread-dot {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #ff5252;
  z-index: 1;
}

.notification-actions button {
  background-color: #1e88e5;
  color: white;
  border: none;
  padding: 6px 12px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 13px;
  transition: background-color 0.3s;
}

.notification-actions button:hover {
  background-color: #0d47a1;
}

.empty-notification {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 0;
  color: #999;
}

.empty-notification img {
  width: 200px;
  height: 150px;
  object-fit: cover;
  margin-bottom: 20px;
  opacity: 0.6;
  border-radius: 8px;
}

.close-btn {
  color: #999;
  font-size: 18px;
  font-weight: bold;
  margin: 0;
  padding: 5px 8px;
  cursor: pointer;
  transition: all 0.2s;
  border-radius: 50%;
  line-height: 1;
  position: absolute;
  top: 50%;
  right: 25px;
  transform: translateY(-50%);
}

.close-btn:hover {
  color: #f44336;
  background-color: #ffebee;
}

.loading,
.no-more {
  text-align: center;
  padding: 30px 20px;
  color: #999;
  font-size: 14px;
  background-color: #fafafa;
  border-radius: 8px;
  margin: 10px 0;
}

.loading p,
.no-more p {
  margin: 0;
}

.loading-spinner {
  width: 30px;
  height: 30px;
  border: 3px solid #f3f3f3;
  border-top: 3px solid #1e88e5;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin: 0 auto 10px;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}
</style>
